<template>
  <editor-content
    class="editor-content"
    :class="{
      'is-empty':
        editorInstance?.isEmpty && editorInstance?.state.doc.childCount <= 1,
      'is-readonly': !editorInstance?.isEditable,
    }"
    :editor="editorInstance"
  />

  <template v-if="editorInstance && editorInstance.isEditable">
    <!-- 拖拽手柄组件 -->
    <BlockMenu />
    <!-- 气泡菜单组件 -->
    <BubbleMenu />
  </template>
</template>

<script setup lang="ts">
import { Editor, EditorContent } from "@tiptap/vue-3";
import {
  inject,
  onMounted,
  onBeforeUnmount,
  nextTick,
  provide,
  type Ref,
} from "vue";
import BlockMenu from "../menus/context/block/index.vue";
import { BubbleMenu } from "../menus/bubble";
import { getDefaultExtensions } from "../../extensions";
import type { EditorProps } from "../../types";
import { syncCommentPositions } from "../../utils/commentPositionSync";

defineOptions({
  name: "EditorContent",
});

// 注入依赖
const documentOptions = inject<Ref<any>>("document");
const container = inject<Ref<string>>("container");
const pageOptions = inject<Ref<any>>("page");
const editorProps = inject<Ref<EditorProps>>("editorProps");

// 创建编辑器实例
const editorInstance: Editor = new Editor({
  extensions: getDefaultExtensions({
    defaultLineHeight: editorProps?.value?.defaultLineHeight,
  }),
  content: documentOptions?.value?.content || "",
  editorProps: {
    attributes: {
      class: "editor-prosemirror editor",
    },
    ...documentOptions?.value?.editorProps,
  },
  parseOptions: documentOptions?.value?.parseOptions || {},
  autofocus: documentOptions?.value?.autofocus || false,
  editable: !documentOptions?.value?.readOnly,
  onUpdate({ editor, transaction }) {
    // 更新文档内容
    if (documentOptions?.value) {
      documentOptions.value.content = editor.getHTML();
    }

    // 同步批注位置
    if (transaction.steps.length > 0) {
      syncCommentPositions(editor, transaction);
    }
  },
});

// 设置storage
const editorInstanceWithStorage = editorInstance as unknown as any;
editorInstanceWithStorage.storage.container = container?.value || "";
editorInstanceWithStorage.storage.page = pageOptions?.value || {};

// 获取inject的editor并赋值
const editor = inject<any>("editor");
editor.value = editorInstance;

// 确保编辑器在挂载后能够获得焦点
onMounted(async () => {
  await nextTick();
  if (editorInstance) {
    editorInstance.commands.focus();
  }
});

// 销毁编辑器实例
onBeforeUnmount(() => {
  editorInstance.destroy();
});
</script>

<style>
@import "../../styles/index.scss";
</style>
